<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Nyan Rainbow</title>
    <link rel="stylesheet" href="../css/style.css">
    <script type="text/javascript" src="../../dist/paper-full.js"></script>
    <script type="text/javascript" src="http://paperjs.org/assets/mediaelement/mediaelement.js"></script>
    <script type="text/paperscript" canvas="canvas">
        // A tribute to Nyan Cat http://www.youtube.com/watch?v=QH2-TGUlwu4
        var mediaElement;
        var playing = false;
        MediaElement('nyan', {
            pluginPath: '/assets/mediaelement/',
            success: function(me) {
                mediaElement = me;
                me.play();
                me.addEventListener('timeupdate', function(time) {
                    if (me.currentTime > 3.7)
                        playing = true;
                });
            }
        });

        var mousePos = view.center + [view.bounds.width / 3, 100];
        var position = view.center;

        function onFrame(event) {
            position += (mousePos - position) / 10;
            var vector = (view.center - position) / 10;
            moveStars(vector * 3);
            moveRainbow(vector, event);
        }

        function onMouseMove(event) {
            mousePos = event.point;
        }

        function onKeyDown(event) {
            if (event.key == 'space')
                project.activeLayer.selected = !project.activeLayer.selected;
        }

        var moveStars = new function() {
            // The amount of symbol we want to place;
            var count = 50;

            // Create a symbol, which we will use to place instances of later:
            var path = new Path.Circle({
                center: new Point(0, 0),
                radius: 5,
                fillColor: 'white',
                strokeColor: 'black'
            });

            var symbol = new SymbolDefinition(path);

            // Place the instances of the symbol:
            for (var i = 0; i < count; i++) {
                // The center position is a random point in the view:
                var center = Point.random() * view.size;
                var placed = symbol.place(center);
                placed.scale(i / count + 0.01);
                placed.data = {
                    vector: new Point({
                        angle: Math.random() * 360,
                        length : (i / count) * Math.random() / 5
                    })
                };
            }

            var vector = new Point({
                angle: 45,
                length: 0
            });

            function keepInView(item) {
                var position = item.position;
                var viewBounds = view.bounds;
                if (position.isInside(viewBounds))
                    return;
                var itemBounds = item.bounds;
                if (position.x > viewBounds.width + 5) {
                    position.x = -item.bounds.width;
                }

                if (position.x < -itemBounds.width - 5) {
                    position.x = viewBounds.width;
                }

                if (position.y > viewBounds.height + 5) {
                    position.y = -itemBounds.height;
                }

                if (position.y < -itemBounds.height - 5) {
                    position.y = viewBounds.height
                }
            }

            return function(vector) {
                // Run through the active layer's children list and change
                // the position of the placed symbols:
                var layer = project.activeLayer;
                for (var i = 0; i < count; i++) {
                    var item = layer.children[i];
                    var size = item.bounds.size;
                    var length = vector.length / 10 * size.width / 10;
                    item.position += vector.normalize(length) + item.data.vector;
                    keepInView(item);
                }
            };
        };

        var moveRainbow = new function() {
            var paths = [];
            var colors = ['red', 'orange', 'yellow', 'lime', 'blue', 'purple'];
            for (var i = 0; i < colors.length; i++) {
                var path = new Path({
                    fillColor: colors[i]
                });
                paths.push(path);
            }

            var count = 30;
            var group = new Group(paths);
            var headGroup;
            var eyePosition = new Point();
            var eyeFollow = (Point.random() - 0.5);
            var blinkTime = 200;
            function createHead(vector, count) {
                var eyeVector = (eyePosition - eyeFollow);
                eyePosition -= eyeVector / 4;
                if (eyeVector.length < 0.00001)
                    eyeFollow = (Point.random() - 0.5);
                if (headGroup)
                    headGroup.remove();
                var top = paths[0].lastSegment.point;
                var bottom = paths[paths.length - 1].firstSegment.point;
                var radius = (bottom - top).length / 2;
                var circle = new Path.Circle({
                    center: top + (bottom - top) / 2,
                    radius: radius,
                    fillColor: 'black'
                });
                circle.scale(vector.length / 100, 1);
                circle.rotate(vector.angle, circle.center);

                innerCircle = circle.clone();
                innerCircle.scale(0.5);
                innerCircle.fillColor = (count % blinkTime < 3)
                    || (count % (blinkTime + 5) < 3) ? 'black' : 'white';
                if (count % (blinkTime + 40) == 0)
                    blinkTime = Math.round(Math.random() * 40) + 200;
                var eye = circle.clone();
                eye.position += eyePosition * radius;
                eye.scale(0.15, innerCircle.position);
                eye.fillColor = 'black';
                headGroup = new Group(circle, innerCircle, eye);
            }

            return function(vector, event) {
                var vector = (view.center - position) / 10;

                if (vector.length < 5)
                    vector.length = 5;
                count += vector.length / 100;
                group.translate(vector);
                var rotated = vector.rotate(90);
                var middle = paths.length / 2;
                for (var j = 0; j < paths.length; j++) {
                    var path = paths[j];
                    var nyanSwing = playing ? Math.sin(event.count / 2) * vector.length : 1;
                    var unitLength = vector.length * (2 + Math.sin(event.count / 10)) / 2;
                    var length = (j - middle) * unitLength + nyanSwing;
                    var top = view.center + rotated.normalize(length);
                    var bottom = view.center + rotated.normalize(length + unitLength);
                    path.add(top);
                    path.insert(0, bottom);
                    if (path.segments.length > 200) {
                        var index = Math.round(path.segments.length / 2);
                        path.segments[index].remove();
                        path.segments[index - 1].remove();
                    }
                    path.smooth();
                }
                createHead(vector, event.count);
                if (mediaElement)
                    mediaElement.setVolume(vector.length / 200);
            }
        }
    </script>
    <style>
        body {
            background: black;
        }
    </style>
</head>
<body>
    <audio id="nyan" src="http://dl.dropbox.com/u/31703/nyan.mp3" autoplay autobuffer preload=none loop style="display:none"></audio>
    <canvas id="canvas" resize hidpi="off"></canvas>
</body>
</html>
